package com.md24housecall.fragment;

import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Color;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.androidquery.AQuery;
import com.androidquery.callback.AjaxCallback;
import com.androidquery.callback.AjaxStatus;
import com.jjoe64.graphview.GraphView.GraphViewData;
import com.jjoe64.graphview.GraphViewSeries;
import com.jjoe64.graphview.GraphViewSeries.GraphViewSeriesStyle;
import com.jjoe64.graphview.GraphViewStyle.GridStyle;
import com.jjoe64.graphview.LineGraphView;
import com.md24housecall.activity.R;
import com.md24housecall.adapter.BaseIHealthAdapter;
import com.md24housecall.adapter.BloodPressureAdapter;
import com.md24housecall.manager.CacheManager;
import com.md24housecall.model.IHealthDataList;
import com.md24housecall.net.UrlBuilder;
import com.md24housecall.util.GlobalConstant;
import com.md24housecall.util.MyLog;
import com.md24housecall.util.Utils;
import com.md24housecall.view.PagingListView;
import com.md24housecall.view.PagingListView.PagingListViewListener;

public class BloodPressureFragment extends Fragment implements PagingListViewListener{
	protected View mainView;
	protected PagingListView lvIHealth;
	protected BaseIHealthAdapter adapter;
	protected AQuery mAQuery;
	protected Utils util=Utils.getInstance();
	protected GlobalConstant constant=GlobalConstant.getInstance();
	protected String userId="",accessToken="",refreshToken="",sc="",sv="",deviceType="",chartTitle="";
	protected List<IHealthDataList> listIHealthData;
	protected ProgressBar mProgressBar;
	protected LinearLayout lnearChart;
	protected CacheManager cacheManager;
	protected int start = 0;
	protected int limit = constant.ITEMIHEATH_NO;
	protected int total = 0;
	private boolean isPaging=false;
	private String nextPageUrl="",urlData="";
	protected boolean isRefresh=true;
	protected boolean isLoadMore=false;
	protected final int MAX_LENGTH_GRAPH=5;
	protected TextView txvTitle1,txvTitle2,txvError;
	protected int mGraphLength;
	protected GraphViewSeries graphSeries;
	protected LineGraphView graphView;
	protected View header;
	protected String[] labels=new String[MAX_LENGTH_GRAPH];
	protected TextView txvChartTitle;
	protected LinearLayout relHeader;
	private final String TOKEN_ERROR_MESSAGE="Token is Unauthorized";
	private final int TIMEOUT=1000;
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		View view=initView(inflater, container);
		mainView=view;
		try{
			cacheManager = CacheManager.getInstance(getActivity());
			for(int i=0;i<MAX_LENGTH_GRAPH;i++){
				labels[i]="";
			}
			initLayout();
			onLoad();
		}catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		return view;
	}
	
	protected View initView(LayoutInflater inflater, ViewGroup container){
		return inflater.inflate(R.layout.blood_pressure_ihealth, container,false);
	}
	
	protected void onRefreshToken(){
		String url=String.format(UrlBuilder.URL_REFRESH_TOKEN_IHEALTH, refreshToken);
		mAQuery.progress(mProgressBar).ajax(url, JSONObject.class, new AjaxCallback<JSONObject>(){
			@Override
			public void callback(String url, JSONObject object,AjaxStatus status) {
				// TODO Auto-generated method stub
				try{
					MyLog.d(GlobalConstant.TAG,"json refresh token: "+object.toString());
//					if(mProgressBar.getVisibility()==View.VISIBLE)
//						mProgressBar.setVisibility(View.GONE);
					if(object!=null){
						accessToken=object.getString("AccessToken");
//						MyLog.d(GlobalConstant.TAG,"new access token: "+accessToken);
						util.savePreferenceString(constant.ACCESSTOKEN_IHEALTH_KEY, getActivity(), accessToken);
						updateUrl();
						isRefresh=true;
						isLoadMore=false;
						if(mProgressBar.getVisibility()==View.GONE)
							mProgressBar.setVisibility(View.VISIBLE);
						getDataServer(urlData);
					}
				}catch (Exception e) {
					// TODO: handle exception
					e.printStackTrace();
				}
			}
		});
	}
	
	private void updateUrl(){
//		Calendar calendar=Calendar.getInstance();
//		long currentTimeStamp=calendar.getTimeInMillis();
////		MyLog.d(GlobalConstant.TAG, "currentTimeStamp: "+currentTimeStamp);
//		int currentDay=calendar.get(Calendar.DATE);
//		int currentMonth=calendar.get(Calendar.MONTH);
//		int currentYear=calendar.get(Calendar.YEAR);
//		if(currentDay>=28)
//			currentDay=28;
//		Calendar c= Calendar.getInstance();
//		c.set(currentYear-1, currentMonth, currentDay);
//		long prevTimeStamp=c.getTimeInMillis();
//		MyLog.d(GlobalConstant.TAG, "prevTimeStamp: "+prevTimeStamp);
//		urlData=String.format(UrlBuilder.URL_GETDATA_IHEALTH, userId,deviceType,accessToken,sc,sv,prevTimeStamp/1000,currentTimeStamp/1000);
		urlData=String.format(UrlBuilder.URL_GETDATA_IHEALTH, userId,deviceType,accessToken,sc,sv);
//		MyLog.d(GlobalConstant.TAG, "urlData: "+urlData);
	}
	
	protected void parseJson(JSONObject object)throws JSONException{
		if(object.has("BPDataList")){
			JSONArray jsonArray=object.getJSONArray("BPDataList");
			lvIHealth.stopRefresh();
			if(jsonArray!=null && jsonArray.length()>0){
				MyLog.d(GlobalConstant.TAG, "parse json");
				clearData();
				for(int i=0;i<jsonArray.length();i++){
					JSONObject jsonObj=jsonArray.getJSONObject(i);
					IHealthDataList dataList=new IHealthDataList();
					dataList.setBPL(jsonObj.getInt("BPL"));
					dataList.setDataId(jsonObj.getString("DataID"));
					dataList.setDataSource(jsonObj.getString("DataSource"));
					dataList.setHP(jsonObj.getInt("HP"));
					dataList.setHR(jsonObj.getInt("HR"));
					dataList.setIsArr(jsonObj.getInt("IsArr"));
					dataList.setLP(jsonObj.getInt("LP"));
					dataList.setLastChangeTime(jsonObj.getLong("LastChangeTime"));
					dataList.setLat(jsonObj.getLong("Lat"));
					dataList.setLong(jsonObj.getLong("Lon"));
					dataList.setDate(jsonObj.getLong("MDate"));
					dataList.setNote(jsonObj.getString("Note"));
					cacheManager.insertBloodPressure(dataList);
				}
			}
		}
	}
	
	private JSONObject getJsonData(JSONObject object)throws JSONException {
//		MyLog.d(GlobalConstant.TAG, "getJsonData: "+object.toString());
		if(object!=null){
			if(object.has("ErrorCode") && object.getString("ErrorDescription").equals(TOKEN_ERROR_MESSAGE)){
				mProgressBar.setVisibility(View.VISIBLE);
				onRefreshToken();
				return null;
			}
			parseJson(object);
//			return object;
		}
		return object;
	}
	
	protected List<IHealthDataList> selectData(){
		List<IHealthDataList> list=cacheManager.selectBloodPressure(start,limit);
		return list;
	}
	
	protected BaseIHealthAdapter getIHealthAdapter(){
		return new BloodPressureAdapter(getActivity(), listIHealthData);
	}
	
	private void updateData(){
		new AsyncTask<Void, Void, List<IHealthDataList>>(){

			@Override
			protected List<IHealthDataList> doInBackground(Void... params) {
				// TODO Auto-generated method stub
				return selectData();
			}
			
			protected void onPostExecute(java.util.List<IHealthDataList> result) {
				if(isRefresh){
					listIHealthData=result;
					if(listIHealthData!=null){
//						header.setVisibility(View.VISIBLE);
						relHeader.setVisibility(View.VISIBLE);
						lvIHealth.setDividerHeight(1);
						adapter=getIHealthAdapter();
						lvIHealth.setAdapter(adapter);
						isRefresh=false;
						checkData();
					}else{
						txvError.setVisibility(View.VISIBLE);
						txvError.setText(getActivity().getString(R.string.msg_no_data));
//						header.setVisibility(View.GONE);
						relHeader.setVisibility(View.GONE);
						lvIHealth.setDividerHeight(0);
						lvIHealth.setAdapter(null);
					}
				}else if(isLoadMore){
					listIHealthData.addAll(result);
					if(adapter!=null)
						adapter.notifyDataSetChanged();
					isLoadMore=false;
				}
				lvIHealth.setPullLoadEnable(isPaging);
			}
			
		}.execute();
		
		
	}
	
	private void getDataServer(final String url){
		MyLog.d(GlobalConstant.TAG,"url_getdata: "+url);
		if(userId!=null && !userId.equals("")){
			mAQuery.progress(mProgressBar).ajax(url, JSONObject.class,TIMEOUT, new AjaxCallback<JSONObject>(){
				public void callback(String url, final JSONObject object, com.androidquery.callback.AjaxStatus status) {
					try{
						if(status.getCode()==200){
							if(object!=null){
								new AsyncTask<Void, Void, JSONObject>(){
	
									@Override
									protected JSONObject doInBackground(Void... params) {
										// TODO Auto-generated method stub
										JSONObject jsonObj=null;
										try{
											jsonObj=getJsonData(object);
										}catch (Exception e) {
											// TODO: handle exception
											e.printStackTrace();
										}
										return jsonObj;
									}
									
									protected void onPostExecute(JSONObject result) {
										if(result!=null){
											if(mProgressBar.getVisibility()==View.VISIBLE)
												mProgressBar.setVisibility(View.GONE);
											if(object.has("NextPageUrl"))
												try {
													nextPageUrl=object.getString("NextPageUrl");
												} catch (Exception e) {
													// TODO Auto-generated catch block
													e.printStackTrace();
												}
											if(!nextPageUrl.equals("")){
												isPaging=true;
											}else{
												isPaging=false;
											}
											updateData();
										}
									}
									
								}.execute();
							}
						}else{
							Toast.makeText(getActivity(), status.getMessage(), Toast.LENGTH_SHORT).show();
						}
					}catch (Exception e) {
						// TODO: handle exception
						if(mProgressBar.getVisibility()==View.VISIBLE)
							mProgressBar.setVisibility(View.GONE);
						lvIHealth.stopRefresh();
						e.printStackTrace();
					}finally{
						lvIHealth.stopLoadMore();
						lvIHealth.stopRefresh();
					}
				}
			});
		}
	}
	
	private void onLoad(){
		total=getTotalData();
		loadData();
	}
	
	private void checkData(){
		if(listIHealthData.size()>0){
			txvError.setVisibility(View.GONE);
			total=listIHealthData.size();
			initChart();
		}else{
			txvError.setVisibility(View.VISIBLE);
			txvError.setText(getActivity().getString(R.string.msg_no_data));
		}
	}
	
	private void loadData(){
		if(total>0){
			mProgressBar.setVisibility(View.GONE);
//			updateData();
			new AsyncTask<Void, Void, List<IHealthDataList>>(){

				@Override
				protected List<IHealthDataList> doInBackground(Void... params) {
					// TODO Auto-generated method stub
					return selectData();
				}
				
				protected void onPostExecute(java.util.List<IHealthDataList> result) {
					listIHealthData=result;
					if(listIHealthData!=null){
						header.setVisibility(View.VISIBLE);
						lvIHealth.setDividerHeight(1);
						adapter=getIHealthAdapter();
						lvIHealth.setAdapter(adapter);
						isRefresh=false;
						checkData();
					}else{
						txvError.setVisibility(View.VISIBLE);
						txvError.setText(getActivity().getString(R.string.msg_no_data));
						header.setVisibility(View.GONE);
						lvIHealth.setDividerHeight(0);
						lvIHealth.setAdapter(null);
					}
					if(util.isNetworkAvailable(getActivity()))
					{
						isRefresh=true;
						getDataServer(urlData);
					}
				}
				
			}.execute();
		}else{
			MyLog.d(GlobalConstant.TAG,"has network: "+util.isNetworkAvailable(getActivity()));
			if(util.isNetworkAvailable(getActivity()))
			{
				isRefresh=true;
				getDataServer(urlData);
			}else{
				Toast.makeText(getActivity(), getActivity().getString(R.string.msg_network_error), Toast.LENGTH_LONG).show();
			}
		}
	}
	
	protected void clearData(){
//		MyLog.d(GlobalConstant.TAG, "clear data: "+isRefresh);
		if(isRefresh){
			cacheManager.clearBloodPressureData();
//			if(listIHealthData!=null && listIHealthData.size()>0)
//				listIHealthData.clear();
		}
	}
	
	protected int getTotalData(){
		int count=cacheManager.getTotalBloodPressure();
		return count;
	}
	
	protected GraphViewData[] loadGraphViewData(){
		GraphViewData[] data=null;
		if(!getActivity().isFinishing()){
			txvTitle1.setText(getActivity().getString(R.string.title_sys_dia));
			txvTitle2.setText(getActivity().getString(R.string.title_bpm));
			data = new GraphViewData[mGraphLength];
//			for(int i=0;i<mGraphLength;i++){
//				data[i]=new GraphViewData(i, listIHealthData.get(i).getHP());
//			}
			int index=0;
			for(int i=mGraphLength-1;i>=0;i--){
				data[index]=new GraphViewData(index, listIHealthData.get(i).getHP());
				index++;
			}
		}
		return data;
	}
	
	protected void initChart(){
		try{
			if(listIHealthData!=null && listIHealthData.size()>0){
				mGraphLength=MAX_LENGTH_GRAPH;
				if(total<MAX_LENGTH_GRAPH)
					mGraphLength=total;
				GraphViewData[] data=loadGraphViewData();
				if(graphSeries==null)
					graphSeries=new GraphViewSeries("", new GraphViewSeriesStyle(Color.parseColor("#33b5e5"), 3), data);
				else{
					graphSeries.resetData(data);
				}
				if(graphView==null)
					graphView = new LineGraphView(getActivity(),"");
//				if(txvChartTitle==null)
//					txvChartTitle=(TextView)mainView.findViewById(R.id.txvChartTitle);
//				txvChartTitle.setText(chartTitle);
				graphView.addSeries(graphSeries); // data
				graphView.getGraphViewStyle().setGridStyle(GridStyle.NONE);
				graphView.setDrawDataPoints(true);
				graphView.setDataPointsRadius(15f);
				graphView.getGraphViewStyle().setHorizontalLabelsColor(Color.WHITE);
		//		graphView.getGraphViewStyle().setTextSize(TEXT_SIZE);
				graphView.getGraphViewStyle().setVerticalLabelsWidth(-20);
				graphView.getGraphViewStyle().setNumVerticalLabels(0);
				graphView.setHorizontalLabels(labels);
		//		graphView.setBackgroundResource(R.drawable.ihealth_background);
				lnearChart.removeView(graphView);
				lnearChart.addView(graphView);
			}
		}catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}
	
	protected void initParams(){
		userId=util.getPreferenceString(constant.USERID_IHEALTH_KEY, getActivity(), "");
		accessToken=util.getPreferenceString(constant.ACCESSTOKEN_IHEALTH_KEY, getActivity(), "");
		refreshToken=util.getPreferenceString(constant.REFRESHTOKEN_IHEALTH_KEY, getActivity(), "");
		sc=constant.SC_BP;
		sv=constant.SV_BP;
		deviceType="bp.json";
		chartTitle=getActivity().getString(R.string.title_blood_pressure);
	}
	
	@SuppressLint("InflateParams")
	private void initLayout(){
		lvIHealth=(PagingListView)mainView.findViewById(R.id.lvIHealth);
		txvError=(TextView)mainView.findViewById(R.id.txvError);
		mProgressBar=(ProgressBar)mainView.findViewById(R.id.progressBar);
		mAQuery=new AQuery(getActivity());
		initParams();
		updateUrl();
		LayoutInflater inflater = (LayoutInflater)getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		header = inflater.inflate(R.layout.chart_view,null);
		lnearChart=(LinearLayout)header.findViewById(R.id.lnearChart);
		txvChartTitle=(TextView)header.findViewById(R.id.txvChartTitle);
		relHeader=(LinearLayout)header.findViewById(R.id.relHeader);
		txvChartTitle.setText(chartTitle);
		txvTitle1=(TextView)header.findViewById(R.id.txvTitle1);
		txvTitle2=(TextView)header.findViewById(R.id.txvTitle2);
		lvIHealth.addHeaderView(header);
		lvIHealth.setPullLoadEnable(isPaging);
		lvIHealth.setPullRefreshEnable(true);
		lvIHealth.setPagingListViewListener(this);
	}

	@Override
	public void onLoadMore() {
		// TODO Auto-generated method stub
		start += constant.ITEMIHEATH_NO;
		limit += constant.ITEMIHEATH_NO;
		if(util.isNetworkAvailable(getActivity())){
			isLoadMore=true;
			getDataServer(Uri.decode(nextPageUrl));
		}else{
			Toast.makeText(getActivity(), getActivity().getString(R.string.msg_network_error), Toast.LENGTH_SHORT).show();
			lvIHealth.stopLoadMore();
		}
	}

	protected void refresh(){
		MyLog.d(GlobalConstant.TAG, "onRefresh blood pressure");
		clearData();
		if(listIHealthData!=null && listIHealthData.size()>0)
			listIHealthData.clear();
	}
	
	@Override
	public void onRefresh() {
		// TODO Auto-generated method stub
		start=0;
		limit=constant.ITEMIHEATH_NO;
		if(util.isNetworkAvailable(getActivity())){
			isRefresh=true;
//			refresh();
			lvIHealth.setPullLoadEnable(false);
			getDataServer(urlData);
		}else{
			Toast.makeText(getActivity(), getActivity().getString(R.string.msg_network_error), Toast.LENGTH_SHORT).show();
			lvIHealth.stopRefresh();
		}
	}
}
